(function () {
    'use strict';

    var $ = tinymce.util.Tools.resolve('tinymce.dom.DomQuery');
    var Tools = tinymce.util.Tools.resolve('tinymce.util.Tools');
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');

    var currentValue = '默认';
    var defaultValue = '默认 5px 10px 15px 20px 25px 30px 35px 40px 50px';

    var constant = function (value) {
        return function () {
            return value;
        };
    };

    var never = constant(false);
    var always = constant(true);

    var none = function () {
        return NONE;
    };

    var NONE = function () {
        var me = {
            fold: function (n, _s) {
                return n();
            },
            is: never,
            isSome: never,
            isNone: always,
            map: none,
            each: function () {}
        };
        return me;
    }();

    var some = function (a) {
        var me = {
            fold: function (n, s) {
                return s(a);
            },
            is: function (v) {
                return a === v;
            },
            isSome: always,
            isNone: never,
            map: function (f) {
                return some(f(a));
            },
            each: function (f) {
                f(a);
            }
        };
        return me;
    };

    var from = function (value) {
        return value === null || value === undefined ? NONE : some(value);
    };

    var Optional = {
        some: some,
        none: none,
        from: from
    };

    var map = function (xs, f) {
        var len = xs.length;
        var r = new Array(len);
        for (var i = 0; i < len; i++) {
            var x = xs[i];
            r[i] = f(x, i);
        }
        return r;
    };

    var Cell = function (initial) {
        var value = initial;
        var get = function () {
            return value;
        };
        var set = function (v) {
            value = v;
        };
        return {
            get: get,
            set: set
        };
    };

    var revocable = function (doRevoke) {
        var subject = Cell(Optional.none());
        var revoke = function () {
            return subject.get().each(doRevoke);
        };
        var clear = function () {
            revoke();
            subject.set(Optional.none());
        };
        var isSet = function () {
            return subject.get().isSome();
        };
        var set = function (s) {
            revoke();
            subject.set(Optional.some(s));
        };
        return {
            clear: clear,
            isSet: isSet,
            set: set
        };
    };

    var destroyable = function () {
        return revocable(function (s) {
            return s.destroy();
        });
    };

    const Indentabe = function (editor, value) {

        if(value === '默认') {
            var blocks = editor.selection.getSelectedBlocks();
            Tools.each(blocks, function(block) {
                editor.dom.setStyle(block, { marginLeft: '', marginRight: '' });
            });
            return !1;
        }

        editor.undoManager.transact(function() {
            editor.focus();
            editor.formatter.toggle('indentabe', { value: String(value) });
            // editor.nodeChanged();
        });
    };

    var getIndentabe = function (editor) {

        var options = editor.getParam('indentabe', defaultValue, 'string').split(' ');

        var apis = new Map();
        var lastApi = destroyable();
        var callback = function () {

            var dom = editor.dom;
            var blocks = editor.selection.getSelectedBlocks();
            var current = editor.queryCommandValue('indentabe') || currentValue;

            Tools.each(blocks, function(block) {
                var _current = dom.getStyle(block,'margin-left');
                if(_current) {
                    current = _current;
                }
            });
            Optional.from(apis.get(current)).fold(function () {
                return lastApi.clear();
            }, function (api) {
                lastApi.set({
                    destroy: function () {
                        api.setActive(!1);
                    }
                });
                api.setActive(!0);
            });
        };

        // editor.on('nodeChange', callback);

        return map(options, function (value, i) {
            return {
                type: 'togglemenuitem',
                text: value,
                onAction: function () {
                    return editor.execCommand('CFYunIndentabe', value);
                },
                onSetup: function (api) {
                    apis.set(value, api);
                    if (i + 1 === options.length) {
                        callback();
                    }
                    return function () {
                        if (i === 0) {
                            // editor.off('nodeChange', callback);
                            lastApi.clear();
                        }
                    };
                }
            };
        });
    };

    const registerMenu = function(editor) {

        editor.ui.registry.getAll().icons.indentabe || editor.ui.registry.addIcon('indentabe','<svg width="18" height="18" viewBox="0 0 1097 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1868"><path d="M36.352 153.014857v-109.714286H1061.302857v109.714286H36.352z m222.061714 275.090286v-109.714286h583.753143v109.714286h-583.68z m0 290.377143v-109.714286h581.046857v109.714286H258.413714zM34.962286 999.350857v-109.714286h1024.292571v109.714286H34.962286zM34.084571 657.993143V375.296l164.571429 141.385143-164.571429 141.312z m1019.392-0.292572l-156.306285-142.262857 156.306285-142.189714v284.452571z" p-id="1869"></path></svg>');

        editor.ui.registry.addMenuButton('indentabe', {
            icon: 'indentabe',
            tooltip: 'Indent at both ends',
            fetch: function (callback) {
                return callback(getIndentabe(editor));
            }
        });
    };

	function Plugin () {
		global.add('indentabe', function (editor) {

            registerMenu(editor);

            editor.on('init', function() {

                editor.formatter.register('indentabe', {
                    block: 'p',
                    // selector: 'p span div',
                    styles: { marginLeft: '%value', marginRight: '%value' },
                });

                editor.addCommand('CFYunIndentabe', function (value) {
                    Indentabe(editor, value);
                });
            });

		});
	}

	Plugin();

}());